#pragma once
#include <windows.h>
#include "CThreadSlotData.h"


class CThreadLocalObject
{
public:
    int m_nSlot;
public:
    ~CThreadLocalObject();

    CNoTrackObject* GetData(CNoTrackObject* (__stdcall* pfnCreateObject)());
    CNoTrackObject* GetDataNA();
};

template <class T>
class CThreadLocal : public CThreadLocalObject
{
    // Attributes
public:
    inline T* GetData()
    {
        T* pData = (T*)CThreadLocalObject::GetData(&CreateObject);
        return pData;
    }
    inline T* GetDataNA()
    {
        T* pData = (T*)CThreadLocalObject::GetDataNA();
        return pData;
    }
    inline operator T* ()
    {
        return GetData();
    }
    inline T* operator->()
    {
        return GetData();
    }

    // Implementation
public:
    static CNoTrackObject* __stdcall CreateObject()
    {
        return new T;
    }
};

#define THREAD_LOCAL(class_name, ident_name) \
	CThreadLocal<class_name> ident_name;

#define EXTERN_THREAD_LOCAL(class_name, ident_name) \
	extern CThreadLocal<class_name> ident_name;
